﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
namespace Init
{
    static class GetClass
    {
        const string DEFAULTNAME = "NameNotFound";
        const string DEFAULTLEVEL = "private";
        const bool DEFAULTSTATIC = false;

        //メンバ変数の取得
        public static void GetClassMember(ref string Code, ref List<Class> CodeClass)
        {
            Regex mm = new Regex(@"##(?<name>[A-Za-z_ :~]+?)##\s*\[(?<main>.*)]\s*;");//クラス用正規表現

            CodeClass.Add(new Class());//Noneクラスを追加する
            CodeClass[0].Name = "None";//名前の設定

            while (mm.Match(Code).Success == true)//見つかる間
            {
                CodeClass.Add(new Class());

                Match m = mm.Match(Code);//マッチした情報を取得
                string name = m.Groups["name"].Value.Replace("##", "");//情報を取得


                if (name.Replace(" ", "") == "None")//もしもNoneが名前に使われていたら
                {
                    throw new ClassNameException("クラス名にNoneは使えません。");//識別子なので蹴る
                }



                CodeClass[CodeClass.Count - 1].Name = name.Replace(" ", ""); ;//名前を登録


                #region debug
#if DEBUG
                Console.WriteLine("[Class::Memb]Name = [{0}]", CodeClass[CodeClass.Count - 1].Name);
#endif
                #endregion



                string Main = m.Groups["main"].Value;//内容を取得
                string CodeTemp = "";

                Match FuncPass = Regex.Match(Main, @"\#Function.*\#EndFunc");//関数範囲取得用正規表現
                if (FuncPass.Success == true)
                {
                    string Func = Main.Substring(FuncPass.Index, FuncPass.Length);//中身の取り出し
                    Main = Main.Remove(FuncPass.Index, FuncPass.Length);//クラス全体からは削除

                    Regex rs = new Regex(@"@(?<Value>.*?:.*?:.*?)\@");//関数名を探す

                    CodeTemp += rs.Replace(Func, @"@${Value}:" + name + " @").Replace("#Function", "").Replace("#EndFunc", "");//置換


                }



                string[] Split = Main.Split(';');//文で分ける


                foreach (string temp in Split)//文毎に処理
                {
                    if (temp == "") continue;

                    string[] var = temp.Split(':');//切り分け
                    Variable v = new Variable();//追加用変数
                    v.Name = var[0].Replace(" ", "");//名前
                    if (var.Length >= 2)//指定子が省略されていなければ
                    {
                        v.AccessLevel = var[1].Replace(" ", "");//アクセスレベル

                        #region debug
#if DEBUG
                        Console.WriteLine("[GetClass::AccessLevel]{0}", var[1].Replace(" ", ""));
#endif
                        #endregion
                    }
                    if (v.Name == "")//名前が空なら
                    {
                        v.Name = DEFAULTNAME;//デフォルト設定を適用
                    }
                    if (v.AccessLevel != "private" && v.AccessLevel != "public")//アクセス指定子でなければ
                    {
                        v.AccessLevel = DEFAULTLEVEL;//デフォルトで設定
                    }

                    CodeClass[CodeClass.Count - 1].Variables.Add(v);//追加
                    #region debug
#if DEBUG
                    int index = CodeClass.Count - 1;
                    Console.WriteLine("[Class::Memb::Variable]Name = [{0}] AccessLevel = [{1}]", CodeClass[index].Variables[CodeClass[index].Variables.Count - 1].Name, CodeClass[index].Variables[CodeClass[index].Variables.Count - 1].AccessLevel);
#endif
                    #endregion

                }



                Code = Code.Remove(m.Index, m.Length);//読み取った部分を削除
                Code += CodeTemp;//関数を追加

            }

        }


    }
}